﻿using SharpGL.Media3D; 

namespace SharpGL.Triangulator.Geometry
{
    /// <summary>
    /// Edge made from two point indexes
    /// </summary>
    public class Edge
    {
        #region Private Fields

        /// <summary>
        /// Start point of edge.
        /// </summary>
        private Point3D firstPoint;

        /// <summary>
        /// End point of edge.
        /// </summary>
        private Point3D secondPoint;

        #endregion Private Fields

        #region Public Constructors

        /// <summary>
        /// Initializes a new edge instance
        /// </summary>
        /// <param name="firstPoint">Start edge vertex</param>
        /// <param name="secondPoint">End edge vertex</param>
        public Edge(Point3D firstPoint, Point3D secondPoint)
        {
            FirstPoint = firstPoint;
            SecondPoint = secondPoint;
        }

        #endregion Public Constructors

        #region Public Methods

        public override int GetHashCode()
        {
            int hashCode = 0;

            hashCode = firstPoint.GetHashCode();
            
            if (hashCode == 0)
                hashCode = secondPoint.GetHashCode();
            else
                hashCode ^= secondPoint.GetHashCode();
            
            return hashCode;
        }

        public override bool Equals(object obj)
        {
            if (obj == null || !(obj is Edge))
            {
                return false;
            }

            return Equals(this, (Edge)obj);
        }

        public bool Equals(Edge edge)
        {
            return Equals(this, edge);
        }

        public static bool Equals(Edge edge1, Edge edge2)
        {
            return (((edge1.FirstPoint == edge2.FirstPoint) && (edge1.SecondPoint == edge2.SecondPoint)) ||
                    ((edge1.FirstPoint == edge2.SecondPoint) && (edge1.SecondPoint == edge2.FirstPoint)));
        }

        public override string ToString()
        {
            return "Edge [" + firstPoint + ", " + secondPoint + "]";
        }

        #endregion Public Methods

        #region Public Operators

        public static bool operator ==(Edge edge1, Edge edge2)
        {
            return edge1.Equals(edge2);
        }

        public static bool operator !=(Edge edge1, Edge edge2)
        {
            return !edge1.Equals(edge2);
        }

        #endregion Public Operators
        
        #region Public Properties

        /// <summary>
        /// Gets or sets the first point of the edge
        /// </summary>
        public Point3D FirstPoint
        {
            get { return firstPoint; }
            set { firstPoint = value; }
        }

        /// <summary>
        /// Gets or sets the second point of the edge
        /// </summary>
        public Point3D SecondPoint
        {
            get { return secondPoint; }
            set { secondPoint = value; }
        }

        #endregion Public Properties
    }
}